/**
 *****************************************************************************
 * DESC ：. 
 * Author : Junwei Zhang 
 * CREATEDATE ：2012-7-4 
 * MODIFYLIST ：       	Name 			 Date 			Reason/Contents
 * 				------------------------------------------------------ 
 * 				 	Junwei Zhang     2012-7-4		Created.
 ****************************************************************************
 **/
package com.me.client;

import com.me.client.JTalkParser.OneMember;
import com.me.client.JTalkParser.OneMessage;

/**
 * 客户端报文协议类. <br/>
 * 上午9:17:33 2012-7-4
 * 
 * @Author <a href="mailto:mestudying@sina.com">Junwei Zhang</a><br/>
 **/
public class JTalkClientProtocal {

	private JTalkClient parentClient = null;

	public JTalkClientProtocal(JTalkClient jTalkClient) {
		this.parentClient = jTalkClient;
	}

	/**
	 * 处理服务器端返回的报文.
	 * 
	 * @param lastPackage
	 * @return
	 */
	public boolean processServerPackage(String lastPackage) {
		// TODO Auto-generated method stub
		JTalkParser parser = new JTalkParser();
		if (!parser.parsing(lastPackage)) {
			return false;
		}

		String serverMessage = parser.getAnswer();
		if (serverMessage != null) {
			if (parser.getAnswerType() == JTalkParser.ANSWER_UPDATE) {
				// System.out.println("---【Client received update notification】---" + parser.getAnswer());
				this.sendUserStatus(false);
			} else if (parser.getAnswerType() == JTalkParser.ANSWER_INFO) {
				System.out.println("---【Client received info】---" + parser.getAnswer());
			}
			if (this.parentClient.state == JTalkClient.STATE_ACCOUNT_CREATION) {
				this.parentClient.closeConnection();
				return true;
			}
		}
		/** 设置登录状态 */
		if (this.parentClient.state == JTalkClient.STATE_LOGGING) {
			this.parentClient.state = JTalkClient.STATE_CONNECTED;
		}
		boolean updateUserList = false;
		// 增加新的用户
		for (int i = 0; i < parser.getMemberNum(); i++) {
			OneMember oneMember = parser.getAMember(i);
			// System.out.println("--[oneMember:]--" + oneMember.name);
			this.parentClient.addMember(oneMember.name, oneMember.status, oneMember.type, null, oneMember.ip, null,
					null);
			if (!updateUserList) {
				updateUserList = true;
			}
		}
		// 处理消息
		for (int i = 0; i < parser.getMessageNum(); i++) {
			OneMessage m = parser.getAMessage(i);
			if (!"command_response".equals(m.messageType)) {
				if("command".equals(m.messageType)){
					String retVal = this.parentClient.getFrontend().getPluginLoader().invokePluginMethod(m.content, m.sender);
					if(retVal == null){
						String errMsg = this.parentClient.getFrontend().getPluginLoader().getLastError();
						System.out.println("*** Can't invoke:" + errMsg);
						this.parentClient.sendMessage(errMsg, m.sender, "error", null, m.messageID);
					}else{
						this.parentClient.sendMessage(retVal, m.sender, "command_response", m.messageSubject, m.messageID);
					}
				}else{
					this.parentClient.addMember(m.sender, m.senderStatus, null, m.content, null, m.messageSubject,
							m.messageType);
				}
			} else {
				this.parentClient.setLastCommandResponse(m.messageID, m.sender, m.content);
			}
		}

		if (updateUserList) {
			this.parentClient.clearUpList(parser);
		}

		return true;
	}

	/**
	 * 向服务器发送注册用户的报文.
	 * 
	 * @param userName
	 * @param password
	 * @return
	 */
	public boolean sendNewAccount(String userName, String password) {
		// TODO Auto-generated method stub
		String message = "<JTALKER><NEW_MEMBER name=\"";
		message += (userName + "\" ");
		message += ("passwd=\"" + MD5Password.hashPassword(password) + "\" />");
		message += "</JTALKER>";
		// System.out.println("--[Send:]" + createAccountMessage);
		// this.out.println(createAccountMessage);
		return this.sendPackage(message);
	}

	/**
	 * 向服务器发送消息.
	 * 
	 * @param message
	 * @return
	 */
	private boolean sendPackage(String message) {
		return this.parentClient.sendToServer(message);
	}

	/**
	 * 用户登录、切换状态时发送消息.
	 * 
	 * @param sendPassword
	 * @return
	 */
	public boolean sendUserStatus(boolean sendPassword) {
		// TODO Auto-generated method stub
		String message = "<JTALKER><MEMBER name=\"";
		message += this.parentClient.userName + "\" status=\"" + this.parentClient.userStatus + "\" ";
		if (sendPassword) {
			message += " passwd=\"" + MD5Password.hashPassword(this.parentClient.password) + "\" />";
		} else {
			message += "/>";
		}
		message += "</JTALKER>";
		return this.sendPackage(message);
	}

	/**
	 * 发送消息.
	 * 
	 * @param message
	 * @param receiver
	 * @param type
	 * @param subject
	 * @param id
	 * @return
	 */
	public boolean sendMessage(String message, String receiver, String type, String subject, String id) {
		if(type == null){
			type = "normal";
		}
		if (receiver != null && (receiver.indexOf(" AT ") != -1)) {
			receiver = receiver.substring(0, receiver.lastIndexOf(" AT "));
		}
		message = toHTMLString(message);
		String stream = "<JTALKER><MESSAGE content=\"";
		stream += (message + "\" ");
		if (receiver != null) {
			stream += ("to=\"" + receiver + "\" type=\"" + type + "\"");
		} else {
			stream += ("type=\"" + type + "\"");
		}
		if (id != null) {
			stream += (" id=\"" + id + "\"");
		}
		if (subject != null) {
			stream += (" subject=\"" + subject + "\"");
		}
		stream += " /></JTALKER>";
		return this.sendPackage(stream);
	}

	/**
	 * 将消息转换为HTML字符.
	 * 
	 * @param message
	 * @return
	 */
	private static String toHTMLString(String in) {
		// TODO Auto-generated method stub
		StringBuffer out = new StringBuffer();
		for (int i = 0; i < in.length(); i++) {
			char c = in.charAt(i);
			if (c == '\'') {
				out.append("&#39;");
			} else if (c == '\"') {
				out.append("&#34;");
			} else if (c == '<') {
				out.append("&lt;");
			} else if (c == '>') {
				out.append("&gt;");
			} else if (c == '&') {
				out.append("&amp;");
			} else if (c == '\n') {
				out.append("_");
			} else if (c == '\r') {
				out.append("_");
			} else {
				out.append(c);
			}
		}
		return out.toString();
	}

}
